﻿using System.Collections.Generic;
using System.Data;
using System.Text;

using SqlExecHelper.Cache;
using SqlExecHelper.Column;
using SqlExecHelper.TempTable;

namespace SqlExecHelper.Update
{
        internal class TempTableUpdate : BatchTempTable, ISqlBasic, IBatchUpdate
        {
                public TempTableUpdate (string table, RunParam param, IDAL myDAL) : base (table, param, null, myDAL)
                {

                }
                public int AffectedRowNum => SqlHelper.RowNum;
                private ISqlSetColumn[] _SetCoumn = null;
                private SqlUpdateColumn[] _ReturnCol = null;
                private ISqlWhere[] _Where = null;
                public StringBuilder GenerateSql (out IDataParameter[] param)
                {
                        this._InitColumn ();
                        StringBuilder sql = new StringBuilder (128);
                        sql.AppendFormat ("update {0} set ", this.FullTableName);
                        List<IDataParameter> adds = new List<IDataParameter> ();
                        SqlTools.InitSetColumn (this._TempTable, sql, this.Config, this._SetCoumn, adds);
                        this._InitOutput (sql);
                        sql.AppendFormat (" from {0} where ", this._TempTable.TableName);
                        SqlTools.InitWhereColumn (this._TempTable, sql, this.Config);
                        if (!this._Where.IsNull ())
                        {
                                SqlTools.AppendWhere (sql, this.Config, this._Where, adds);
                        }
                        param = adds.ToArray ();
                        return sql;
                }
                private void _InitColumn ()
                {
                        this.Column.ForEach (a =>
                         {
                                 if (a.ColType == SqlColType.通用)
                                 {
                                         a.ColType = SqlColType.修改;
                                 }
                         });
                }
                private void _InitOutput (StringBuilder sql)
                {
                        if (this._ReturnCol.IsNull ())
                        {
                                return;
                        }
                        sql.Append (" output ");
                        this._ReturnCol.ForEach (a =>
                         {
                                 sql.Append (a.ToString ());
                         });
                        sql.Remove (sql.Length - 1, 1);
                }

                public bool Update (params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return false;
                        }
                        this._Where = where;
                        return SqlHelper.ExecuteNonQuery (this, this._MyDAL) > 0;
                }


                public T[] Update<T> (params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return null;
                        }
                        this._Where = where;
                        this._ReturnCol = ClassStructureCache.GetReturnColumn (typeof (T));
                        return SqlHelper.GetTable<T> (this, this._MyDAL);
                }

                public T[] Update<T> (SqlEventPrefix prefix, params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return null;
                        }
                        this._Where = where;
                        this._ReturnCol = ClassStructureCache.GetReturnColumn (typeof (T), prefix);
                        return SqlHelper.GetTable<T> (this, this._MyDAL);
                }

                public T[] Update<T> (string column, params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return null;
                        }
                        this._Where = where;
                        this._ReturnCol = new SqlUpdateColumn[]
                        {
                                new SqlUpdateColumn(column, SqlEventPrefix.deleted)
                        };
                        return SqlHelper.GetTable<T> (this, this._MyDAL);
                }
                public Result[] Update<Result> (ISqlSetColumn[] columns, SqlEventPrefix prefix, params ISqlWhere[] where)
                {
                        this._Where = where;
                        this._SetCoumn = columns;
                        this._ReturnCol = ClassStructureCache.GetReturnColumn (typeof (Result), prefix);
                        return SqlHelper.GetTable<Result> (this, this._MyDAL);
                }
                public Result[] Update<Result> (ISqlSetColumn[] columns, string rcolumn, SqlEventPrefix prefix, params ISqlWhere[] where)
                {
                        this._Where = where;
                        this._SetCoumn = columns;
                        this._ReturnCol = new SqlUpdateColumn[]
                        {
                                new SqlUpdateColumn(rcolumn, prefix)
                        };
                        return SqlHelper.GetTable<Result> (this, this._MyDAL);
                }
                public T[] Update<T> (string column, SqlEventPrefix prefix, params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return null;
                        }
                        this._Where = where;
                        this._ReturnCol = new SqlUpdateColumn[]
                        {
                                new SqlUpdateColumn(column, prefix)
                        };
                        return SqlHelper.GetTable<T> (this, this._MyDAL);
                }



                public bool Update (ISqlSetColumn[] columns, params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return false;
                        }
                        this._SetCoumn = columns;
                        this._Where = where;
                        return SqlHelper.ExecuteNonQuery (this, this._MyDAL) != -2;
                }

                public Result[] Update<Result> (string column, SqlEventPrefix prefix, ISqlSetColumn[] columns, params ISqlWhere[] where)
                {
                        if (!this._TempTable.Save ())
                        {
                                return null;
                        }
                        this._SetCoumn = columns;
                        this._Where = where;
                        this._ReturnCol = new SqlUpdateColumn[]
                       {
                        new SqlUpdateColumn(column, prefix)
                       };
                        return SqlHelper.GetTable<Result> (this, this._MyDAL);
                }
        }
}
